Skip to content

fix(167): file list name sort should use natural order (not character… - #201

Open
Mcchen1008 wants to merge 1 commit into
OpenListTeam:mainfrom
Mcchen1008:fix-natural-sort
Open

Mcchen1008 wants to merge 1 commit into
OpenListTeam:mainfrom
Mcchen1008:fix-natural-sort

Conversation

@Mcchen1008

Copy link
Copy Markdown
Collaborator

Summary / 摘要

  • 修因:OpenListTeam/OpenList-Worker#167 文件列表按名称排序时 Worker 端出来的是字符序(file1, file10, file2, file20),而官方 Go 版 OpenList 出来的是自然数序(file1, file2, file3, file10, file11, file20),导致从 Go 版切到 Worker 版后排序看起来"乱了"。
  • 查了官方 Go 版代码 internal/model/config.go → model.SortFiles(orderBy="name"),发现它用的是 github.com/maruel/natural.Compare(经典自然序),TS 端则是在 src/backend/internal/driver/sort.ts 里用了 String(a.name).localeCompare(String(b.name)),导致排序行为不一致。 我以 maruel/natural 的行为为唯一事实来源,port 了对应的自然序比较器 compareNames 并只改了一个调用点。所有名(name/filename/file)排序口味的共享排序都会生效。

Implementation changes / 实现改动

  • src/backend/internal/driver/sort.ts
    • 新增 compareNames(a, b):开源实现 CommonPrefix(遇到数字停止)+ leadingDigits + 数值比较 + 前导零处理,语义与 maruel/natural.Compare 完全一致。
    • sortFileItems 的 name 分支从 localeCompare 改为 compareNames;size/time/modified 分支不受影响,且仍保持"文件夹优先"约定。
    • 不引入额外依赖、不修改公共 API、不改存储格式;(这个只在界面上排序变化,不改写任何数据)
  • src/backend/internal/driver/sort.test.ts(新增):13 个 Tests,覆盖 file1/10/2/20/3/11、纯数字、含点文件名、前导零、大小写(ASCII 码位序,和 Go strings.Compare 一致)、中西文混合、空串、文件夹优先、倒序、size/modified 不变、非破坏性等。
  • 验证了和 maruel/natural.Compare 82,000 对随机字符串的 cross-check(0 差异,见 zz_crosscheck 思路),不保留临时验证文件,避免 .test 污染。

User-visible behavior / 用户可感知的行为变化

  • 文件列表(/api/fs/list 等入口)按名称排序时,file1.txt, file2.txt, file3.txt, file10.txt 顺序显示;之前 file10, file20 会排在 file2, file3 前面。
  • 所有使用 sortFileItems(..., "name", ...) 的驱动列表(webdav/onedrive/...)都受这个自然序影响;asc/desc 与文件夹优先逻辑不变。
  • Media/S3/Emby 内部排序(localeCompare)未改动 — 只有列表页冲击。

Related Issues / 关联 Issue

Closes #167

Testing / 测试

  • pnpm run test:drivers — 239 pass(含新增的 sort.test.ts)
  • pnpm run test:pkg — 33 pass
  • pnpm run test:store — 15 pass
  • pnpm run test:model — 39 pass
  • pnpm run test:regress — 71/71 pass
  • pnpm run test:server — 238/239 pass,唯一失败 storage_update_guangyapan(在 clean stash 基线上复现,与排序修改无关,pre-existing)
  • tsc --noEmit 无错,prettier --check 通过
  • 手动复现:新建 file1, file2, file3, file10 文件名的列表,该 PR 排序从 字符序 变成 file1, file2, file3, file10;Go 版行为(通过 maruel/natural)完全相同。

Checklist / 检查清单

  • 我已阅读 CONTRIBUTING。
  • 我确认此贡献符合仓库 license + 贡献规范。
  • 我使用 prettier 格式化了变更代码(Vite 部分未改动)。
  • 我提交分支到 fork 到了 Mcchen1008/OpenList-Worker:fix-natural-sort(主分支未改,需要 maintainers 合并 PR)。

AI Disclosure / AI 使用声明

  • 此 PR 包含 AI 辅助内容。
    使用范围:代码生成(compareNames 自然序 port)+ 测试生成 + 文档撰写。
  • 我已审核并验证 PR 中的所有 AI 辅助内容(随附 zz_crosscheck 对比验证思路)。
  • 我可以在没有 AI 工具的情况下重现所有 AI 辅助内容(port 来源于 GitHub 公开库 github.com/maruel/natural/native,所有逻辑与单元测试都可复述)。

@PIKACHUIM PIKACHUIM linked an issue Nov 13, 2026 that may be closed by this pull request
4 tasks done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG] 文件排序问题

1 participant